﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using G28BS.Models;
using System.Data.Entity;
using System.Web.Security;

using G28BS.Code;

namespace G28BS.Controllers
{
    [Authorize]
    [HandleError]
    public class GameRoomController : BaseAppController
    {
        private IAppRepository repo = null;
        private IUserService userService = null;

        public GameRoomController()
        {
            repo = new AppRepository();
            userService = new AppUserService();
        }

        public GameRoomController(IAppRepository r, IUserService u)
        {
            repo = r;
            userService = u;
        }

        //
        // GET: /GameRoom/

        // Redirect to frontpage when trying to access Index of GameRoom.
        public ActionResult Index()
        {
            // Create an exception
            // Game g = null;
            // int a = g.gameID;
            return RedirectToAction("Index", "Home");
        }

        /*
         * Join method is for users to be added to gameRooms.
         * id parameter is gameRoomID of existing gameRoom.
         */
        public ActionResult Join(int id)
        {
            // Try to load game room, and verify it exists.
            var gameRoom = repo.gameRooms.SingleOrDefault(gR => gR.gameRoomID == id);
            if (gameRoom == null)
            {
                return new HttpNotFoundResult();
            }
            // For some reason EF does not load game into gameRoom. Do it manually.
            var game = repo.games.SingleOrDefault(g => g.gameID == gameRoom.gameID);
            if (game == null)
            {
                // Maybe throw an exception here instead since this means something is not working correctly.
                return new HttpNotFoundResult();
            }
            gameRoom.game = game;

            // TODO: check for invite to enter game, if we implement that.

            // Check if game is accepting players, redirect otherwise.
            if (gameRoom.state != GameRoomStates.Waiting)
            {
                // Set up a message and redirect to frontpage since no empty slot.
                TempData["message"] = "Þessi leikur tekur ekki við fleiri leikmönnum!";
                TempData["messageType"] = "error";
                return RedirectToAction("Index", "Home");
            }

            // Check if user is already a player in game.
            int currentUserID = userService.GetUserID();
            Slot playerSlot = gameRoom.slots.FirstOrDefault(s => s.userProfileID == currentUserID);
            if (playerSlot != null)
            {
                // Set up a message and redirect to frontpage since no empty slot.
                TempData["message"] = "Þú ert nú þegar leikmaður í þessu spili!";
                TempData["messageType"] = "error";
                return RedirectToAction("Index", "Home");
            }

            // Get empty slot for player.
            Slot emptySlot = gameRoom.slots.FirstOrDefault(s => s.occupied == false);
            if (emptySlot == null)
            {
                // Set up a message and redirect to frontpage since no empty slot.
                TempData["message"] = "Ekki pláss fyrir fleiri leikmenn í þessu spili!";
                TempData["messageType"] = "error";
                return RedirectToAction("Index", "Home");
            }
            // Assign user information to slot.
            emptySlot.occupied = true;
            emptySlot.userProfileID = currentUserID;
            emptySlot.userName = userService.GetUserName();

            string image = (from x in repo.userProfiles
                            where x.UserId == currentUserID
                            select x.userImage).FirstOrDefault();

            /*string filePath = "~/Images/Profile/" + imageName;

            if (System.IO.File.Exists(filePath))
            {
                emptySlot.userImage = "/Images/Profile/" + imageName;
            }
            else
            {
                emptySlot.userImage = "/Images/avatar.png";
            }*/
            if (image != null)
                emptySlot.userImage = "/Images/Profile/" + image;
            else
                emptySlot.userImage = "/Images/avatar.png";

            repo.Save();

            ViewData["currentUserID"] = currentUserID;
            ViewData["currentUserName"] = userService.GetUserName();
            ViewData["slotNumber"] = emptySlot.slotNumber;
            return View("Room", gameRoom);
        }

        /*
         * Create method is for users to create a new gameRoom.
         * id parameter is gameID of selected game.
         */
        [HttpGet]
        public ActionResult Create(int id)
        {
            // Load game and check if it exists.
            var gameType = repo.games.SingleOrDefault(game => game.gameID == id);
            if (gameType == null)
            {
                return new HttpNotFoundResult();
            }
            // Game ok, create a game room.
            var gameRoom = new GameRoom
            {
                gameRoomName = gameType.name + " " + DateTime.Now.ToString()
            };
            // Add the game and set starting state.
            gameRoom.game = gameType;
            gameRoom.state = GameRoomStates.Waiting;
            gameRoom.dateCreated = DateTime.Now;

            // Get id of current user and set as host.
            int currentUserID = userService.GetUserID();
            gameRoom.host = repo.userProfiles.FirstOrDefault(u => u.UserId == currentUserID);
            // Create the player slots and add to gameRoom
            List<Slot> slots = _CreateSlots(gameRoom);
            gameRoom.slots = slots;
            repo.AddSlots(slots);

            repo.AddGameRoom(gameRoom);
            repo.Save();

            ViewData["currentUserID"] = currentUserID;
            ViewData["currentUserName"] = userService.GetUserName();
            ViewData["slotNumber"] = 0;
            return View("Room", gameRoom);
        }

        private List<Slot> _CreateSlots(GameRoom gr)
        {
            /*string filePath = "~/Images/Profile/" + gr.host.userImage;
            string image;
            if (System.IO.File.Exists(filePath))
            {
                image = "/Images/Profile/" + gr.host.userImage;
            }
            else
            {
                image = "/Images/avatar.png";
            }*/
            string image;
            if (gr.host.userImage != null)
                image = "/Images/Profile/" + gr.host.userImage;
            else
                image = "/Images/avatar.png";

            List<Slot> s = new List<Slot>();
            // Add slot for host player.
            s.Add(new Slot { gameRoomID = gr.gameRoomID, occupied = true, ready = false, slotNumber = 0, userProfileID = gr.host.UserId, userName = gr.host.UserName, userImage = image });
            // Create slots for users to occupy.
            for (int i = 1; i < gr.game.maxPlayers; i++)
            {
                s.Add(new Slot { gameRoomID = gr.gameRoomID, occupied = false, ready = false, slotNumber = i });
            }
            return s;
        }
    }
}
